home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  15.0 KB  |  642 lines

  1. /* misc.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Id: misc.c,v 1.28 1995/11/30 00:19:19 brianp Exp $
  26.  
  27. $Log: misc.c,v $
  28.  * Revision 1.28  1995/11/30  00:19:19  brianp
  29.  * changed version string to 1.2.5
  30.  *
  31.  * Revision 1.27  1995/11/22  13:35:40  brianp
  32.  * check CC.NewState in glClear
  33.  *
  34.  * Revision 1.26  1995/11/13  22:08:29  brianp
  35.  * removed comma from extensions string
  36.  *
  37.  * Revision 1.25  1995/11/03  17:39:48  brianp
  38.  * removed unused variables
  39.  *
  40.  * Revision 1.24  1995/10/27  20:29:19  brianp
  41.  * added GL_EXT_polygon_offset to extensions string
  42.  *
  43.  * Revision 1.23  1995/10/19  15:48:05  brianp
  44.  * added gamma support
  45.  * changed DD.clear_color arguments to GLubytes
  46.  *
  47.  * Revision 1.22  1995/10/14  16:29:48  brianp
  48.  * new glReadBuffer and glDrawBuffer implementations
  49.  * added glColor/IndexMask support when clearing color buffer
  50.  *
  51.  * Revision 1.21  1995/09/20  18:20:58  brianp
  52.  * prototype device driver changes described
  53.  *
  54.  * Revision 1.20  1995/09/13  14:51:52  brianp
  55.  * moved glGetError to context.c
  56.  *
  57.  * Revision 1.19  1995/09/08  14:08:51  brianp
  58.  * use GL_QUADS instead of GL_POLYGON in glRect functions
  59.  * updated version string to 1.2.3
  60.  *
  61.  * Revision 1.18  1995/07/24  18:55:49  brianp
  62.  * added dd_finish()
  63.  *
  64.  * Revision 1.17  1995/07/18  20:23:58  brianp
  65.  * updated version string for 1.2.2
  66.  *
  67.  * Revision 1.16  1995/06/29  22:10:47  brianp
  68.  * don't call dd_clear_index() when in RGB mode
  69.  * don't call dd_clear_color() when in CI mode
  70.  *
  71.  * Revision 1.15  1995/06/09  21:48:38  brianp
  72.  * changed version string to 1.2.1
  73.  *
  74.  * Revision 1.14  1995/05/24  13:00:15  brianp
  75.  * updated version query functions to return 1.2
  76.  *
  77.  * Revision 1.13  1995/05/22  21:02:41  brianp
  78.  * Release 1.2
  79.  *
  80.  * Revision 1.12  1995/05/17  13:52:37  brianp
  81.  * implemented glIndexMask(0) and glColorMask(0,0,0,0)
  82.  *
  83.  * Revision 1.11  1995/05/12  16:57:22  brianp
  84.  * replaced CC.Mode!=0 with INSIDE_BEGIN_END
  85.  *
  86.  * Revision 1.10  1995/05/12  16:28:41  brianp
  87.  * added const to glGetString prototype
  88.  *
  89.  * Revision 1.9  1995/04/17  14:48:19  brianp
  90.  * updated glGetString for 1.1.4 beta
  91.  *
  92.  * Revision 1.8  1995/03/30  21:08:25  brianp
  93.  * glClear limited to scissor box, not viewport!
  94.  *
  95.  * Revision 1.7  1995/03/13  20:55:59  brianp
  96.  * new read buffer logic
  97.  *
  98.  * Revision 1.6  1995/03/10  16:25:19  brianp
  99.  * updated glGetString for blending extensions
  100.  *
  101.  * Revision 1.5  1995/03/08  15:15:04  brianp
  102.  * removed garbage characters from tail of file
  103.  *
  104.  * Revision 1.4  1995/03/08  15:10:02  brianp
  105.  * added support for dd_clear_index and dd_clear_color
  106.  *
  107.  * Revision 1.3  1995/03/07  14:21:10  brianp
  108.  * updated for new XSetForeground/GC scheme
  109.  *
  110.  * Revision 1.2  1995/03/04  19:29:44  brianp
  111.  * 1.1 beta revision
  112.  *
  113.  * Revision 1.1  1995/02/24  14:24:57  brianp
  114.  * Initial revision
  115.  *
  116.  */
  117.  
  118.  
  119. /*
  120.  * Miscellaneous functions
  121.  */
  122.  
  123.  
  124. #include <stdlib.h>
  125. #include <string.h>
  126. #include "accum.h"
  127. #include "context.h"
  128. #include "depth.h"
  129. #include "dd.h"
  130. #include "gamma.h"
  131. #include "list.h"
  132. #include "macros.h"
  133. #include "masking.h"
  134. #include "stencil.h"
  135.  
  136.  
  137.  
  138. void
  139. glClearIndex( GLfloat c )
  140. {
  141.    if (CC.CompileFlag) {
  142.       gl_save_clearindex( c );
  143.    }
  144.    if (CC.ExecuteFlag) {
  145.       if (INSIDE_BEGIN_END) {
  146.      gl_error( GL_INVALID_OPERATION, "glClearIndex" );
  147.      return;
  148.       }
  149.       CC.Color.ClearIndex = (GLuint) c;
  150.       if (!CC.RGBAflag) {
  151.      /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
  152.      (*DD.clear_index)( CC.Color.ClearIndex );
  153.       }
  154.    }
  155. }
  156.  
  157.  
  158.  
  159. void
  160. glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
  161. {
  162.    if (CC.CompileFlag) {
  163.       gl_save_clearcolor( red, green, blue, alpha );
  164.    }
  165.    if (CC.ExecuteFlag) {
  166.       if (INSIDE_BEGIN_END) {
  167.      gl_error( GL_INVALID_OPERATION, "glClearColor" );
  168.      return;
  169.       }
  170.  
  171.       CC.Color.ClearColor[0] = CLAMP( red,   0.0F, 1.0F );
  172.       CC.Color.ClearColor[1] = CLAMP( green, 0.0F, 1.0F );
  173.       CC.Color.ClearColor[2] = CLAMP( blue,  0.0F, 1.0F );
  174.       CC.Color.ClearColor[3] = CLAMP( alpha, 0.0F, 1.0F );
  175.  
  176.       if (CC.RGBAflag) {
  177.          GLubyte r = (GLint) (CC.Color.ClearColor[0] * CC.RedScale);
  178.          GLubyte g = (GLint) (CC.Color.ClearColor[1] * CC.GreenScale);
  179.          GLubyte b = (GLint) (CC.Color.ClearColor[2] * CC.BlueScale);
  180.          GLubyte a = (GLint) (CC.Color.ClearColor[3] * CC.AlphaScale);
  181.          if (CC.RedGamma!=1.0 || CC.GreenGamma!=1.0 || CC.BlueGamma!=1.0) {
  182.             gl_apply_gamma( 1, &r, &g, &b );
  183.          }
  184.      (*DD.clear_color)( r, g, b, a );
  185.       }
  186.    }
  187. }
  188.  
  189.  
  190.  
  191.  
  192. /*
  193.  * Clear the color buffer when glColorMask or glIndexMask is in effect.
  194.  */
  195. static void
  196. clear_color_buffer_with_masking( void )
  197. {
  198.    GLint x, y, height, width;
  199.  
  200.    /* Compute region to clear */
  201.    if (CC.Scissor.Enabled) {
  202.       x = CC.Scissor.Xmin;
  203.       y = CC.Scissor.Ymin;
  204.       height = CC.Scissor.Ymax - CC.Scissor.Ymin + 1;
  205.       width = CC.Scissor.Xmax - CC.Scissor.Xmin + 1;
  206.    }
  207.    else {
  208.       x = 0;
  209.       y = 0;
  210.       height = CC.BufferHeight;
  211.       width = CC.BufferWidth;
  212.    }
  213.  
  214.    if (CC.RGBAflag) {
  215.       /* RGBA mode */
  216.       GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  217.       GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  218.       GLubyte r = CC.Color.ClearColor[0] * CC.RedScale;
  219.       GLubyte g = CC.Color.ClearColor[1] * CC.GreenScale;
  220.       GLubyte b = CC.Color.ClearColor[2] * CC.BlueScale;
  221.       GLubyte a = CC.Color.ClearColor[3] * CC.AlphaScale;
  222.       GLint i;
  223.       if (CC.RasterMask & GAMMA_BIT) {
  224.          gl_apply_gamma( 1, &r, &g, &b );
  225.       }
  226.       for (i=0;i<height;i++,y++) {
  227.          MEMSET( red,   (int) r, width );
  228.          MEMSET( green, (int) g, width );
  229.          MEMSET( blue,  (int) b, width );
  230.          MEMSET( alpha, (int) a, width );
  231.          gl_mask_color_span( width, x, y, red, green, blue, alpha );
  232.          (*DD.write_color_span)( width, x, y, red, green, blue, alpha, NULL );
  233.       }
  234.    }
  235.    else {
  236.       /* Color index mode */
  237.       GLuint indx[MAX_WIDTH];
  238.       GLubyte mask[MAX_WIDTH];
  239.       GLint i, j;
  240.       MEMSET( mask, 1, width );
  241.       for (i=0;i<height;i++,y++) {
  242.          for (j=0;j<width;j++) {
  243.             indx[j] = CC.Color.ClearIndex;
  244.          }
  245.          gl_mask_index_span( width, x, y, indx );
  246.          (*DD.write_index_span)( width, x, y, indx, mask );
  247.       }
  248.    }
  249. }
  250.  
  251.  
  252.  
  253.  
  254. void
  255. glClear( GLbitfield mask )
  256. {
  257.    if (CC.CompileFlag) {
  258.       gl_save_clear( mask );
  259.    }
  260.    if (CC.ExecuteFlag) {
  261.       if (INSIDE_BEGIN_END) {
  262.      gl_error( GL_INVALID_OPERATION, "glClear" );
  263.      return;
  264.       }
  265.  
  266.       if (CC.NewState) {
  267.          gl_update_state();
  268.       }
  269.  
  270.       if (mask & GL_DEPTH_BUFFER_BIT) {
  271.      gl_clear_depth_buffer();
  272.       }
  273.  
  274.       if (mask & GL_ACCUM_BUFFER_BIT) {
  275.      gl_clear_accum_buffer();
  276.       }
  277.  
  278.       if (mask & GL_COLOR_BUFFER_BIT) {
  279.          if (CC.Color.SWmasking) {
  280.             clear_color_buffer_with_masking();
  281.          }
  282.          else {
  283.             (*DD.clear)( !CC.Scissor.Enabled,
  284.                          CC.Scissor.X, CC.Scissor.Y,
  285.                          CC.Scissor.Width, CC.Scissor.Height );
  286.          }
  287.       }
  288.  
  289.       if (mask & GL_STENCIL_BUFFER_BIT) {
  290.      gl_clear_stencil_buffer();
  291.       }
  292.    }
  293. }
  294.  
  295.  
  296.  
  297. void
  298. glIndexMask( GLuint mask )
  299. {
  300.    if (CC.CompileFlag) {
  301.       gl_save_indexmask( mask );
  302.    }
  303.    if (CC.ExecuteFlag) {
  304.       if (INSIDE_BEGIN_END) {
  305.      gl_error( GL_INVALID_OPERATION, "glIndexMask" );
  306.      return;
  307.       }
  308.       CC.Color.IndexMask = mask;
  309.       CC.NewState = GL_TRUE;
  310.    }
  311. }
  312.  
  313.  
  314.  
  315. void
  316. glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha )
  317. {
  318.    if (CC.CompileFlag) {
  319.       gl_save_colormask( red, green, blue, alpha );
  320.    }
  321.    if (CC.ExecuteFlag) {
  322.       if (INSIDE_BEGIN_END) {
  323.      gl_error( GL_INVALID_OPERATION, "glColorMask" );
  324.      return;
  325.       }
  326.       CC.Color.ColorMask = (red << 3) | (green << 2) | (blue << 1) | alpha;
  327.       CC.NewState = GL_TRUE;
  328.    }
  329. }
  330.  
  331.  
  332.  
  333. const GLubyte *
  334. glGetString( GLenum name )
  335. {
  336.    static char *vendor = "Brian Paul";
  337.    static char *renderer = "Mesa";
  338.    static char *version = "1.2.5";
  339.    static char *extensions = "GL_EXT_blend_color GL_EXT_blend_minmax GL_EXT_blend_logic_op GL_EXT_blend_subtract GL_EXT_polygon_offset";
  340.  
  341.    if (INSIDE_BEGIN_END) {
  342.       gl_error( GL_INVALID_OPERATION, "glGetError" );
  343.       return (GLubyte *) 0;
  344.    }
  345.  
  346.    switch (name) {
  347.       case GL_VENDOR:
  348.          return (GLubyte *) vendor;
  349.       case GL_RENDERER:
  350.          return (GLubyte *) renderer;
  351.       case GL_VERSION:
  352.          return (GLubyte *) version;
  353.       case GL_EXTENSIONS:
  354.          return (GLubyte *) extensions;
  355.       default:
  356.          gl_error( GL_INVALID_ENUM, "glGetString" );
  357.          return (GLubyte *) 0;
  358.    }
  359. }
  360.  
  361.  
  362.  
  363. void
  364. glFinish( void )
  365. {
  366.    /* Don't compile into display list */
  367.    if (INSIDE_BEGIN_END) {
  368.       gl_error( GL_INVALID_OPERATION, "glFinish" );
  369.       return;
  370.    }
  371.    (*DD.finish)();
  372. }
  373.  
  374.  
  375.  
  376. void
  377. glFlush( void )
  378. {
  379.    /* Don't compile into display list */
  380.    if (INSIDE_BEGIN_END) {
  381.       gl_error( GL_INVALID_OPERATION, "glFlush" );
  382.       return;
  383.    }
  384.    (*DD.flush)();
  385. }
  386.  
  387.  
  388.  
  389. void glHint( GLenum target, GLenum mode )
  390. {
  391.    if (CC.CompileFlag) {
  392.       gl_save_hint( target, mode );
  393.    }
  394.    if (CC.ExecuteFlag) {
  395.       if (INSIDE_BEGIN_END) {
  396.      gl_error( GL_INVALID_OPERATION, "glHint" );
  397.      return;
  398.       }
  399.       if (mode!=GL_DONT_CARE && mode!=GL_FASTEST && mode!=GL_NICEST) {
  400.      gl_error( GL_INVALID_ENUM, "glHint(mode)" );
  401.      return;
  402.       }
  403.       switch (target) {
  404.      case GL_FOG_HINT:
  405.         CC.Hint.Fog = mode;
  406.         break;
  407.      case GL_LINE_SMOOTH_HINT:
  408.         CC.Hint.LineSmooth = mode;
  409.         break;
  410.      case GL_PERSPECTIVE_CORRECTION_HINT:
  411.         CC.Hint.PerspectiveCorrection = mode;
  412.         break;
  413.      case GL_POINT_SMOOTH_HINT:
  414.         CC.Hint.PointSmooth = mode;
  415.         break;
  416.      case GL_POLYGON_SMOOTH_HINT:
  417.         CC.Hint.PolygonSmooth = mode;
  418.         break;
  419.      default:
  420.         gl_error( GL_INVALID_ENUM, "glHint(target)" );
  421.       }
  422.    }
  423. }
  424.  
  425.  
  426.  
  427. void glDrawBuffer( GLenum mode )
  428. {
  429.    if (CC.CompileFlag) {
  430.       gl_save_drawbuffer( mode );
  431.    }
  432.    if (CC.ExecuteFlag) {
  433.       if (INSIDE_BEGIN_END) {
  434.      gl_error( GL_INVALID_OPERATION, "glDrawBuffer" );
  435.      return;
  436.       }
  437.       switch (mode) {
  438.      case GL_FRONT:
  439.      case GL_FRONT_LEFT:
  440.             if ( (*DD.set_buffer)( GL_FRONT ) == GL_FALSE ) {
  441.                gl_error( GL_INVALID_ENUM, "glDrawBuffer" );
  442.                return;
  443.             }
  444.             CC.Color.DrawBuffer = mode;
  445.             break;
  446.      case GL_BACK:
  447.      case GL_BACK_LEFT:
  448.             if ( (*DD.set_buffer)( GL_BACK ) == GL_FALSE) {
  449.                gl_error( GL_INVALID_ENUM, "glDrawBuffer" );
  450.                return;
  451.             }
  452.             CC.Color.DrawBuffer = mode;
  453.             break;
  454.      case GL_NONE:
  455.      case GL_FRONT_RIGHT:
  456.      case GL_BACK_RIGHT:
  457.      case GL_LEFT:
  458.      case GL_RIGHT:
  459.      case GL_FRONT_AND_BACK:
  460.      case GL_AUX0:
  461.             gl_error( GL_INVALID_OPERATION, "glDrawBuffer" );
  462.             break;
  463.          default:
  464.             gl_error( GL_INVALID_ENUM, "glDrawBuffer" );
  465.       }
  466.    }
  467. }
  468.  
  469.  
  470.  
  471. void glReadBuffer( GLenum mode )
  472. {
  473.    if (CC.CompileFlag) {
  474.       gl_save_readbuffer( mode );
  475.    }
  476.    if (CC.ExecuteFlag) {
  477.       if (INSIDE_BEGIN_END) {
  478.      gl_error( GL_INVALID_OPERATION, "glReadBuffer" );
  479.      return;
  480.       }
  481.       switch (mode) {
  482.      case GL_FRONT:
  483.      case GL_FRONT_LEFT:
  484.             if ( (*DD.set_buffer)( GL_FRONT ) == GL_FALSE) {
  485.                gl_error( GL_INVALID_ENUM, "glReadBuffer" );
  486.                return;
  487.             }
  488.             CC.Pixel.ReadBuffer = mode;
  489.             break;
  490.      case GL_BACK:
  491.      case GL_BACK_LEFT:
  492.             if ( (*DD.set_buffer)( GL_BACK ) == GL_FALSE) {
  493.                gl_error( GL_INVALID_ENUM, "glReadBuffer" );
  494.                return;
  495.             }
  496.             CC.Pixel.ReadBuffer = mode;
  497.             break;
  498.      case GL_FRONT_RIGHT:
  499.      case GL_BACK_RIGHT:
  500.      case GL_LEFT:
  501.      case GL_RIGHT:
  502.      case GL_AUX0:
  503.         gl_error( GL_INVALID_OPERATION, "glReadBuffer" );
  504.             break;
  505.          default:
  506.             gl_error( GL_INVALID_ENUM, "glReadBuffer" );
  507.       }
  508.    }
  509.  
  510.    /* Remember, the draw buffer is the default state */
  511.    (void) (*DD.set_buffer)( CC.Color.DrawBuffer );
  512. }
  513.  
  514.  
  515.  
  516. void glRectd( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 )
  517. {
  518.    /*
  519.     * TODO:  optimize all glRect calls to issue gl_save_vertex and/or
  520.     * gl_vertex calls, etc. depending on CC.ExecuteFlag and
  521.     * CC.CompileFlag.
  522.     */
  523.  
  524.    if (INSIDE_BEGIN_END) {
  525.       gl_error( GL_INVALID_OPERATION, "glRectd" );
  526.       return;
  527.    }
  528.    glBegin( GL_QUADS );
  529.    glVertex2d( x1, y1 );
  530.    glVertex2d( x2, y1 );
  531.    glVertex2d( x2, y2 );
  532.    glVertex2d( x1, y2 );
  533.    glEnd();
  534. }
  535.  
  536.  
  537. void glRectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
  538. {
  539.    if (INSIDE_BEGIN_END) {
  540.       gl_error( GL_INVALID_OPERATION, "glRectf" );
  541.       return;
  542.    }
  543.    glBegin( GL_QUADS );
  544.    glVertex2f( x1, y1 );
  545.    glVertex2f( x2, y1 );
  546.    glVertex2f( x2, y2 );
  547.    glVertex2f( x1, y2 );
  548.    glEnd();
  549. }
  550.  
  551.  
  552. void glRecti( GLint x1, GLint y1, GLint x2, GLint y2 )
  553. {
  554.    if (INSIDE_BEGIN_END) {
  555.       gl_error( GL_INVALID_OPERATION, "glRecti" );
  556.       return;
  557.    }
  558.    glBegin( GL_QUADS );
  559.    glVertex2i( x1, y1 );
  560.    glVertex2i( x2, y1 );
  561.    glVertex2i( x2, y2 );
  562.    glVertex2i( x1, y2 );
  563.    glEnd();
  564. }
  565.  
  566.  
  567. void glRects( GLshort x1, GLshort y1, GLshort x2, GLshort y2 )
  568. {
  569.    if (INSIDE_BEGIN_END) {
  570.       gl_error( GL_INVALID_OPERATION, "glRects" );
  571.       return;
  572.    }
  573.    glBegin( GL_QUADS );
  574.    glVertex2s( x1, y1 );
  575.    glVertex2s( x2, y1 );
  576.    glVertex2s( x2, y2 );
  577.    glVertex2s( x1, y2 );
  578.    glEnd();
  579. }
  580.  
  581.  
  582. void glRectdv( const GLdouble *v1, const GLdouble *v2 )
  583. {
  584.    if (INSIDE_BEGIN_END) {
  585.       gl_error( GL_INVALID_OPERATION, "glRectdv" );
  586.       return;
  587.    }
  588.    glBegin( GL_QUADS );
  589.    glVertex2d( v1[0], v1[1] );
  590.    glVertex2d( v2[0], v1[1] );
  591.    glVertex2d( v2[0], v2[1] );
  592.    glVertex2d( v1[0], v2[1] );
  593.    glEnd();
  594. }
  595.  
  596.  
  597. void glRectfv( const GLfloat *v1, const GLfloat *v2 )
  598. {
  599.    if (INSIDE_BEGIN_END) {
  600.       gl_error( GL_INVALID_OPERATION, "glRectfv" );
  601.       return;
  602.    }
  603.    glBegin( GL_QUADS );
  604.    glVertex2f( v1[0], v1[1] );
  605.    glVertex2f( v2[0], v1[1] );
  606.    glVertex2f( v2[0], v2[1] );
  607.    glVertex2f( v1[0], v2[1] );
  608.    glEnd();
  609. }
  610.  
  611.  
  612. void glRectiv( const GLint *v1, const GLint *v2 )
  613. {
  614.    if (INSIDE_BEGIN_END) {
  615.       gl_error( GL_INVALID_OPERATION, "glRectiv" );
  616.       return;
  617.    }
  618.    glBegin( GL_QUADS );
  619.    glVertex2i( v1[0], v1[1] );
  620.    glVertex2i( v2[0], v1[1] );
  621.    glVertex2i( v2[0], v2[1] );
  622.    glVertex2i( v1[0], v2[1] );
  623.    glEnd();
  624. }
  625.  
  626.  
  627. void glRectsv( const GLshort *v1, const GLshort *v2 )
  628. {
  629.    if (INSIDE_BEGIN_END) {
  630.       gl_error( GL_INVALID_OPERATION, "glRectsv" );
  631.       return;
  632.    }
  633.    glBegin( GL_QUADS );
  634.    glVertex2s( v1[0], v1[1] );
  635.    glVertex2s( v2[0], v1[1] );
  636.    glVertex2s( v2[0], v2[1] );
  637.    glVertex2s( v1[0], v2[1] );
  638.    glEnd();
  639. }
  640.  
  641.  
  642.